package com.michaelbulava.TFS.ui.wizards.share;

import com.intellij.ide.wizard.CommitStepException;
import com.intellij.openapi.module.Module;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.table.JBTable;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
import com.michaelbulava.TFS.ui.dialogs.vc.ServerItemTreeDialog;
import com.michaelbulava.TFS.ui.framework.wizard.ExtendedWizardStep;
import com.michaelbulava.TFS.ui.wizards.common.IConnectWizard;
import com.michaelbulava.TFS.ui.wizards.common.IShareWizard;
import com.microsoft.tfs.core.clients.versioncontrol.path.ServerPath;
import com.microsoft.tfs.util.StringUtil;

import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.DocumentEvent;
import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventObject;

/**
 * Created by MichaelA on 7/24/2015.
 */
public class MapModulesToTFSWizardStep extends ExtendedWizardStep {
    public static final Object STEP_ID = new Object();
    private final IShareWizard wizard;
    private ModuleMappingControl control;

    public MapModulesToTFSWizardStep(IShareWizard wizard) {
        super("");
        this.wizard = wizard;
        control = new ModuleMappingControl();
    }

    @Override
    public Object getStepId() {
        return STEP_ID;
    }

    @Override
    public Object getNextStepId() {
        return wizard.getNextStepId(this);
    }

    @Override
    public Object getPreviousStepId() {
        return wizard.getPreviousStepId(this);
    }

    @Override
    public void commit(CommitType commitType) throws CommitStepException {

    }

    @Override
    public boolean isComplete() {
        for(int i  =0; i <wizard.getModulesToShare().length; i++){
            Module m = wizard.getModulesToShare()[i];
            String v = wizard.getModuleShareLocation(m);
            if (v == null || v.length() == 0)
                return false;
        }
        return true;
    }

    @Override
    public JComponent getComponent() {
        return control;
    }

    @Override
    public JComponent getPreferredFocusedComponent() {
        return null;
    }

    private ModuleMappingTableModel tableModel = new ModuleMappingTableModel();

    private class ModuleMappingControl extends JPanel{
        private JTextPane locationMessageTextPane;
        private JBTable moduleMappingTable;

        public ModuleMappingControl(){
            setLayout(new GridLayoutManager(2, 1, new Insets(4, 4, 4, 4), -1, -1));

            final JPanel panel2 = new JPanel();
            panel2.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
            add(panel2, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
                    GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                    GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0,
                    false));

            locationMessageTextPane = new JTextPane();
            panel2.add(locationMessageTextPane, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER,
                    GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW,
                    GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(150, 50), null, 0, false));

            final JScrollPane scrollPane1 = new JBScrollPane();
            add(scrollPane1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER,
                    GridConstraints.FILL_BOTH,
                    GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW,
                    GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0,
                    false));

            moduleMappingTable = new JBTable();


            moduleMappingTable.setDefaultRenderer(Module.class, new ModuleMappingTableModuleRenderer());
            //moduleMappingTable.setDefaultRenderer(String.class, new ModuleMappingTableModuleRenderer());
            moduleMappingTable.setDefaultEditor(String.class, new ModuleMappingPathModuleEditor());
            ListSelectionModel cellSelectionModel = moduleMappingTable.getSelectionModel();
            cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            moduleMappingTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            moduleMappingTable.setModel(tableModel);
            moduleMappingTable.setRowHeight(30);
            scrollPane1.setViewportView(moduleMappingTable);
        }


        private void updateRowHeights(){

        }
    }

    private class ModuleMappingTableModel extends AbstractTableModel{


        public ModuleMappingTableModel(){
            super();
        }

        @Override
        public int getRowCount() {
            return wizard.getModulesToShare().length;
        }

        @Override
        public int getColumnCount() {
            return 2;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Module currentModule = wizard.getModulesToShare()[rowIndex];
            if (columnIndex == 0){
                return currentModule;
            } else {
                return wizard.getModuleShareLocation(currentModule);
            }
        }

        @Override
        public Class getColumnClass(int c) {
            switch(c){
                case 0:
                    return Module.class;
                case 1:
                    return String.class;
                default:
                    return String.class;
            }
        }

        @Override
        public String getColumnName(int column){
            switch(column){
                case 0:
                    return "Module";
                case 1:
                    return "TFS Location";
                default:
                    return "";
            }
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            if (columnIndex == 1)
                return true;
            return false;
        }
    }

    private class ModuleMappingTableModuleRenderer extends DefaultTableCellRenderer{
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                                       boolean hasFocus, int row, int column) {
            if (value instanceof Module){
                Module myValue = (Module)value;
                return super.getTableCellRendererComponent(table, myValue.getName(), isSelected, hasFocus, row, column);
            } else if ((value instanceof String) || column == 1) {
                String path = "";
                if (value instanceof String)
                    path = (String)value;
                TFSPathSelectionControl control = new TFSPathSelectionControl(path);
                control.setBackground(isSelected ? table.getSelectionBackground() : control.getBackground());
                control.setForeground(isSelected ? table.getSelectionForeground() : control.getForeground());
                return control;
                //return super.getTableCellRendererComponent(table, path, isSelected, hasFocus, row, column);
            } else if ((column == 2)){
                JButton button = new JButton();
                button.setText("..");
                button.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {

                    }
                });
                return button;
            } else {
                return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            }

        }
    }

    private class ModuleMappingPathModuleEditor extends AbstractCellEditor implements TableCellEditor {
        private TFSPathSelectionControl control = new TFSPathSelectionControl(null);

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            String path = "";
            if (value instanceof String)
                path = (String)value;
            control.setForModule(wizard.getModulesToShare()[row]);
            control.setBackground(isSelected ? table.getSelectionBackground() : control.getBackground());
            control.setForeground(isSelected ? table.getSelectionForeground() : control.getForeground());
            control.setTFSLocation(path);
            return control;
        }


        @Override
        public Object getCellEditorValue() {
            return control.getTFSLocation();
        }
    }

    private class TFSPathSelectionControl extends JPanel{
        private JTextField TFSLocationTextField;
        private JButton Browsebutton;

        private Module forModule;

        private TFSPathSelectionControl(String pathValue){

            setLayout(new GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1));
            TFSLocationTextField = new JTextField();
            if (pathValue != null && pathValue.length() > 0 )
                TFSLocationTextField.setText(pathValue);
            else
                TFSLocationTextField.setText("");

            TFSLocationTextField.getDocument().addDocumentListener(new DocumentAdapter() {
                @Override
                protected void textChanged(DocumentEvent documentEvent) {
                    locationChanged();
                }
            });

            add(TFSLocationTextField, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST,
                    GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW,
                    GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false));
            Browsebutton = new JButton();
            Browsebutton.setText("..");
            Browsebutton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (forModule != null){
                        ServerItemTreeDialog dialog = new ServerItemTreeDialog(Browsebutton,
                                wizard.getProject(), wizard.getWorkspace(), "Select TFS Path", forModule.getName());
                        if (dialog.showAndGet()){
                            TFSLocationTextField.setText(dialog.getSelectedPath());
                        }
                    }
                }
            });
            add(Browsebutton, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_EAST,
                    GridConstraints.FILL_NONE,
                    GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                    GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
            final Spacer spacer1 = new Spacer();
            //panel1.add(spacer1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
        }

        public void setForModule(Module module){
            this.forModule = module;
        }

        public String getTFSLocation(){
            return TFSLocationTextField.getText();
        }

        public void setTFSLocation(String value){
            if (value == null)
                value = "";
            TFSLocationTextField.setText(value);
        }

        public boolean isLocationValid(){
            String value = getTFSLocation();
            if (value == null || value.length() == 0)
                return false;
            if (value == ServerPath.ROOT)
                return false;
            if (!value.startsWith(ServerPath.ROOT))
                return false;
            //TODO there are probably more checks needed at some point

            return true;
        }

        private void locationChanged(){
            if (isLocationValid() && forModule != null){
                String path = getTFSLocation();
                wizard.setModuleShareLocation(forModule, path);
            }
            tableModel.fireTableDataChanged();
            fireStateChanged();
        }
    }
}
